/******************************************************************************
* SVN­Version­Information:
* ­­­­­­­­­­­­­­­­­­­­­­­­---------------------
* $LastChangedRevision: 6 $
* $LastChangedBy: c.a.duevel $
* $LastChangedDate: 2009-08-26 15:12:37 +0000 (Wed, 26 Aug 2009) $
* $HeadURL: http://robofight.googlecode.com/svn/trunk/ClientJavaFX/src/de/hft_stuttgart/robofight/client/javafx/GameLobby.fx $
******************************************************************************/

package de.hft_stuttgart.robofight.client.javafx;

import de.hft_stuttgart.botwar.common.commands.ChatCmd;
import de.hft_stuttgart.botwar.common.models.GameInfo;
import de.hft_stuttgart.robofight.client.java.JPlayer;
import de.hft_stuttgart.robofight.client.javafx.Constants;
import de.hft_stuttgart.robofight.client.javafx.util.*;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.animation.transition.FadeTransition;
import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.input.MouseEvent;
import javafx.scene.Node;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.scene.control.TextBox;
import com.sun.javafx.scene.control.caspian.ButtonSkin;
import javafx.scene.Cursor;
import javafx.scene.control.Button;
import javafx.scene.paint.Color;
import de.hft_stuttgart.botwar.common.interfaces.IRemotePlayer;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.animation.transition.PauseTransition;

/**
 * @author ralf.dauenhauer@gmx.de, michael.rieker@web.de
 */

public class GameLobby extends CustomNode {

    package var getNodeByName : function(nodeName : String) : Node;
    package var getPlayer : function() : JPlayer;
    package var switchNode : function(className : String) : Void;
    public var chatList : java.util.List;
    var readyToInit : Boolean = false;
    var pauseTransition : PauseTransition = PauseTransition {
        node: this.group as Node
        duration: 3s
    }
    var chatTextBox : TextBox = TextBox {
        font : Constants.FONT_TEXTFIELD,
        layoutX : 160.0, layoutY : 520.0,
        width: 400
        height : 18
        skin: Constants.getTextBoxSkin()
        onKeyPressed: function(evt: KeyEvent): Void {
             if (evt.code == KeyCode.VK_ENTER) {
                sendChatMsg();
             }
        }
    }


    public var gameList : java.util.List;
    public var playerList : java.util.List;
    public var playerRobotIDs : java.util.List;

    // check actual infos about players and games
    var checkPlayerInfos : Timeline = Timeline {
        repeatCount: Timeline.INDEFINITE
        keyFrames : [
            KeyFrame {
                time : 3s
                canSkip : true
                action: function() {
                    createPlayerList();
                }
            }
        ]
    }

    // check status and chat messages
    var checkStatusTimeline : Timeline = Timeline {
        repeatCount: Timeline.INDEFINITE
        keyFrames : [
            KeyFrame {
                time : 1s
                canSkip : true
                action: function() { 
                    checkStatus();
                    refreshChat();
                    if (readyToInit){
                        if (getPlayer().getPlayerIsRunningGame()){
                            stopAllTimelines();
                            switchNode("Arena");
                        } 
                    }
                }
            }
        ]
    }

    function checkStatus(){
        var kicked = getPlayer().kicked();
        if(not kicked.equals("")){
            stopAllTimelines();
            getPlayer().resetKicked();
            getPlayer().leaveGameLobby();
            insert Message {
                    msg: kicked
                    msgBoxBackground: getNodeByName("msgBoxmessageBox")
            } into group.content;
            pauseTransition.action = function() {
                switchNode("Lobby");
            }
            pauseTransition.play();
        }

    }

   var sendbutton = javafx.scene.control.Button {
        text: "send"
        cursor: Cursor.HAND
        layoutY: 518, layoutX: 580
        height: 22
        font : Constants.FONT_TEXTFIELD,
        action: function() {
            sendChatMsg();
        }
        skin: ButtonSkin {
            borderFill: Color.BLACK
            cornerRadius: 15
            highlightFill: Color.BLACK
            shadowFill: Color.BLACK
            textFill: Color.BLACK
            fill: Color.GRAY
        }
    }

    public var chatTable = TableNode {
        layoutX : 165, layoutY : 429
        scrollStepSize: -1
        w: 500
        h: 80
    }

   /**
    * creates and refreshes the GaemList, only if something has changed
    */
    function refreshChat(){
        checkStatus();
        chatList = getPlayer().getGameLobbyChatMsg();
        var cnt = 0;
        var yPos : Number = 12;
        if(chatList.size() > chatTable.tableEntries.size()){
            chatTable.tableEntries = null;
            while (cnt < chatList.size()){
                var message : ChatCmd;
                var color = Color.WHITE;
                message = chatList.get(cnt) as ChatCmd;
                if(message.getChatType().equals(IRemotePlayer.CHATTYPE.PRIVATE)){
                    color = Color.rgb(23, 185, 241);
                }
                insert Text {
                    content: "{message.getChatSender() as String}: {message.getChatMessage() as String}";
                    font: Constants.FONT_CHAT
                    fill: color
                    layoutY: yPos
                } into chatTable.tableEntries;
                yPos += 12;
                cnt++;
            }
            if(chatTable.tableEntries.size()>6){
                chatTable.scrollUp();
            }
        }
    }

    /**
    * creates the GameInfoList
    */
    function createGameInfoList(){
       var gameInfo : GameInfo = getPlayer().getGameInfo(getPlayer().getGameID());
       insert Text { fill: Color.WHITE font: Constants.FONT_TEXTFIELD content: "Name: {gameInfo.getGameName()}   |  Map: {gameInfo.getMapName()}"
       } into this.gameInfosGroup.content;
       insert Text { fill: Color.WHITE  font: Constants.FONT_TEXTFIELD layoutY: 25 content: "Max.Bots per Player: {gameInfo.getMaxBots()}"
       } into this.gameInfosGroup.content;
       insert Text { fill: Color.WHITE  font: Constants.FONT_TEXTFIELD layoutY: 50 content: "Max.Players: {gameInfo.getMaxPlayers()}   |  Max. Bot Costs: < {getPlayer().getMaxCoinAmountByLevel(gameInfo.getMaxPlayerLevel())}"
       } into this.gameInfosGroup.content;
       insert Text { fill: Color.WHITE   font: Constants.FONT_TEXTFIELD layoutY: 75 content: "Gameowner: {gameInfo.getGameOwner()}"
       } into this.gameInfosGroup.content;
    }


   /**
    * creates and refreshes the PlayerList, only if something has changed
    */
    function createPlayerList(){
        if (getPlayer().kicked().equals("")){
            playerList = getPlayer().getPlayersByGameID();
            playerGroup.content = null;
            var cnt : Integer = 0;
            var owner :Boolean = getPlayer().amIOwner();
            while(cnt < playerList.size()){
                 insert TableEntry {
                                textColumns : 300
                                var tmp = cnt;
                                text: getPlayer().getShortPlayerInfo(playerList.get(cnt).toString());
                                infoBox :  getNodeByName("infoEntry") as Group;
                                tooltipAction : function() : String {
                                    getPlayer().getFullPlayerInfo(playerList.get(tmp).toString());
                                }
                                setAction : function(nothing : Integer) : Void {
                                    getPlayer().kickPlayer(playerList.get(tmp).toString());
                                }
                                statusLight : getPlayerStatus(playerList.get(cnt).toString());
                                layoutY : cnt * 27
                                kickPlayer : owner
                                playerID : playerList.get(tmp) as String;
                 } into playerGroup.content;
                 cnt++;
            }
         }
    }

   /**
    * returns a greenLight if the player is ready to init
    */
    function getPlayerStatus(playerID : String) : Node{
        if(getPlayer().getPlayerStatus(playerID)){
            return getNodeByName("greenLight");
        } else {
            getNodeByName("redLight");
        }
    }


   /**
    * creates and refreshes the PlayerList, only if something has changed
    */
    function createBotList(){
            var cnt = 0;
            var entry : TableEntry;
            var yPos : Number = 20;
            myBotsTable.tableEntries = null;
            while(cnt < playerRobotIDs.size()){
                 entry = TableEntry {
                                entryID : playerRobotIDs.get(cnt) as Integer;
                                textColumns : 300
                                setAction : setActiveBots
                                var tmp = cnt;
                                text: getPlayer().getPlayerRobotInfo(playerRobotIDs.get(cnt) as Integer);
                                infoBox :  getNodeByName("infoEntry") as Group;
                                tooltipAction : function() : String {
                                    getPlayer().getFullPlayerRobotInfo(playerRobotIDs.get(tmp) as Integer);
                                }
                                getNodeByName : getNodeByName
                                statusLight : getNodeByName("redLight");
                                y: yPos
                 }
                 yPos += entry.boundsInLocal.height;
                 insert entry into myBotsTable.tableEntries;
                 cnt++;
            }
    }

    var playerGroup = Group {
        var fxzLayout = getNodeByName("gameLobbyPlayerFrame").layoutBounds;
        layoutX : fxzLayout.minX - 105;
        layoutY : fxzLayout.minY + 53;
    }

    var myBotsTable = TableNode {
        var fxzLayout = getNodeByName("gameLobbyMyBotsFrame").layoutBounds;
        layoutX : fxzLayout.minX + 15;
        layoutY : fxzLayout.minY + 53;
        h: 260
        w: 350
    }


    var gameInfosGroup = Group {
        var fxzLayout = getNodeByName("gameLobbyGameInfosFrame").layoutBounds;
        layoutX : fxzLayout.minX -25;
        layoutY : fxzLayout.minY + 70;
    }

    public function setActiveBots(robotID : Integer) : Void {
        getPlayer().setActiveBots(robotID);
    }

    public function kickPlayer(playerID : String) : Void {
        getPlayer().kickPlayer(playerID);
    }


    var waitingText = Text {
                    x: 3 y : 11
                    content: "Waiting . .";
                    font : Constants.FONT_CHAT
                    fill : Color.WHITE
    }
    var fadeTransition = FadeTransition {
        duration: 2s
        node: waitingText
        fromValue: 1.0
        toValue: 0.2
        repeatCount: 50
        autoReverse: true
    }
    var infoBoxWaitForPlayers : Group = Group {
        var fxzLayout = getNodeByName("gameLobbySetReady").layoutBounds;
        layoutX : fxzLayout.minX + 6;
        layoutY : fxzLayout.minY + 8;
        content: [
            Group {
                layoutX : 5
                content: [
                Rectangle {
                    arcHeight: 5
                    arcWidth: 5
                    width: 110, height: 15
                    fill: Color.BLACK
                }
                waitingText
                ]
            }
            Group {
                layoutX: 116
                content: [
                Rectangle {
                    arcHeight: 5
                    arcWidth: 5
                    width: 15, height: 15
                    fill: Color.RED
                },
                Line {
                    startX: 2, startY: 2
                    endX: 13, endY: 13
                    strokeWidth: 2
                    stroke: Color.BLACK
                }
                Line {
                    startX: 2, startY: 13
                    endX: 13, endY: 2
                    strokeWidth: 2
                    stroke: Color.BLACK
                }
                ]
                onMouseClicked: function( e: MouseEvent ):Void {
                    getPlayer().setUnReadyToInit();
                    readyToInit = false;
                    createBotList();
                    infoBoxWaitForPlayers.toBack();
                }
            }
        ]
    }


    var group : Group = Group {
            content: [
                getNodeByName("background"),
                getNodeByName("logo_small"),
                getNodeByName("gameLobbyPlayerFrame"),
                getNodeByName("gameLobbyGameInfosFrame"),
                getNodeByName("gameLobbyMyBotsFrame"),
                getNodeByName("gameLobbyChat"),
                getNodeByName("logout"),
                Rectangle {
                    var fxzLayout = getNodeByName("logout").layoutBounds;
                    x : fxzLayout.minX;
                    y : fxzLayout.minY;
                    width : 80
                    height : 15
                    cursor : Cursor.HAND;
                    onMouseClicked : function( e : MouseEvent) : Void {
                        getPlayer().logout();
                        switchNode("Login");
                    }
                    opacity:0
                },
                playerGroup,
                myBotsTable,
                gameInfosGroup,
                Button { //setReady
                    layoutX : getNodeByName("gameLobbySetReady").layoutBounds.minX
                    layoutY : getNodeByName("gameLobbySetReady").layoutBounds.minY
                    text: "setReady"
                    action: function():Void {
                        if(not readyToInit){
                            startGame();
                        }
                    }
                    font: Constants.FONT_BUTTON
                    cursor : Cursor.HAND
                    width: 150
                    height : 30
                    skin : Constants.getButtonSkin();
                },
                Button { //leaveGame
                    layoutX : getNodeByName("gameLobbyLeaveGame").layoutBounds.minX
                    layoutY : getNodeByName("gameLobbyLeaveGame").layoutBounds.minY
                    text: "leaveGame"
                    action: function():Void {
                        getPlayer().leaveGameLobby();
                        stopAllTimelines();
                        switchNode("Lobby");
                    }
                    font: Constants.FONT_BUTTON
                    cursor : Cursor.HAND
                    width: 150
                    height : 30
                    skin : Constants.getButtonSkin();
                },
                chatTextBox,
                chatTable,
                sendbutton
            ]
    };

   init {
        chatTextBox.requestFocus();
        playerRobotIDs = getPlayer().getPlayerRobotIDs();
        playerList = getPlayer().getPlayersByGameID();
        createBotList();
        createGameInfoList();
        createPlayerList();
        checkPlayerInfos.play();
        checkStatusTimeline.play();
    }

    // returns GameLobby Node
    public override function create(): Node {
        return group;
    }

    function startGame(){
        if(not readyToInit) {
            var errorMsg : String;
            if((errorMsg = getPlayer().setReadyToInit()) == null){
                readyToInit = true;
                insert infoBoxWaitForPlayers into this.group.content;
                fadeTransition.play();
            } else {
                insert Message {
                        msg: errorMsg
                        msgBoxBackground: getNodeByName("msgBoxmessageBox")
                } into group.content;
            }
        }
    }

    function stopAllTimelines() : Void {
        checkPlayerInfos.stop();
        checkStatusTimeline.stop();
        getPlayer().cleanChatMessages();
    }

    function sendChatMsg() : Void {
        var tmp = getPlayer().sendGameChatMsg({chatTextBox.text} as String);
        if(tmp==""){
            chatTextBox.text = "";
            chatTextBox.requestFocus();
        } else {
            insert Message {
                msgBoxBackground: getNodeByName("msgBoxmessageBox")
                title: "Info"
                msg: tmp
            } into group.content;
        }
    }

}
